// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import iView from 'iview'
import i18n from '@/locale'
import config from '@/config'
import importDirective from '@/directive'
import 'iview/dist/styles/iview.css'
import './index.less'
import '@/assets/icons/iconfont.css'
import './lib/base.less' // 公共样式
// 安装图片预览插件
import preview from 'vue-photo-preview'
import 'vue-photo-preview/dist/skin.css'
// 引入axios
import axios from 'axios'
import Qs from 'qs'
// 处理时间戳
import moment from 'moment'
// 引入echarts表格
import echarts from 'echarts'
import VueQuillEditor from 'vue-quill-editor'
// require styles 引入样式
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'

Vue.use(VueQuillEditor)

Vue.use(preview)
Vue.prototype.$echarts = echarts
Vue.prototype.axios = axios
Vue.prototype.qs = Qs

// const baseURL = 'http://testmanager.eglobal.vip' //测试环境
const baseURL = 'http://192.168.0.132:8098'
axios.defaults.baseURL = baseURL

// 格式化语言版本
Vue.prototype.languageFormat = function(language) {
	switch(language) {
		case 'zh_CN':
			return '中文'
			break
		case 'en_US':
			return '英语'
			break
		case 'vi_VN':
			return '越南语'
			break
		default:
			return '#'
			break
	}
}

//彻底冻结对象
//先冻结传入对象，获取传入对象的key值，循环冻结
Vue.prototype.constantize = function(obj) {
	Object.freeze(obj);
	Object.keys(obj).forEach((key, i) => {
		if(typeof obj[key] === 'object') {
			constantize(obj[key]);
		}
	});
}

Vue.prototype.quillOption = {
	modules: {
		toolbar: [
			['bold', 'italic', 'underline', 'strike', 'blockquote', 'code-block'], //加粗，斜体，下划线，删除线
			[{
				'header': 1
			}, {
				'header': 2
			}], // 标题，键值对的形式；1、2表示字体大小
			[{
				'list': 'ordered'
			}, {
				'list': 'bullet'
			}], //列表
			[{
				'script': 'sub'
			}, {
				'script': 'super'
			}], // 上下标
			[{
				'indent': '-1'
			}, {
				'indent': '+1'
			}], // 缩进
			[{
				'direction': 'rtl'
			}], // 文本方向

			[{
				'size': ['small', false, 'large', 'huge']
			}], // 字体大小
			[{
				'header': [1, 2, 3, 4, 5, 6, false]
			}], //几级标题

			[{
				'color': []
			}, {
				'background': []
			}], // 字体颜色，字体背景颜色
			[{
				'font': []
			}], //字体
			[{
				'align': []
			}], //对齐方式

			['clean'], //清除字体样式
		]
	}
}

Vue.prototype.resetSetItem = function(key, newVal) {
	if(key === 'userDetail') {
		// 创建一个StorageEvent事件
		var newStorageEvent = document.createEvent('StorageEvent')
		const storage = {
			setItem: function(k, val) {
				localStorage.setItem(k, val)

				// 初始化创建的事件
				newStorageEvent.initStorageEvent('setItem', false, false, k, null, val, null, null)

				// 派发对象
				window.dispatchEvent(newStorageEvent)
			}
		}
		return storage.setItem(key, newVal)
	}
}

// 时间戳转化
Vue.prototype.stringToTime = function(str) {
	let time = new Date(str)
	var y = time.getFullYear()
	var m = time.getMonth() + 1
	var d = time.getDate()
	var h = time.getHours()
	var mm = time.getMinutes()
	var s = time.getSeconds()
	return y + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d) + ' ' + time.toTimeString().substr(0, 8)
}

/*
 * 处理精度丢失 digit为精度
 * 思路：为了避免产生精度差异，我们要把需要计算的数字乘以 10 的 n 次幂，换算成计算机能够精确识别的整数，然后再除以 10 的 n 次幂，大部分编程语言都是这样处理精度差异的，我们就借用过来处理一下 JS 中的浮点数精度误差
 * @param f {number} 运算数
 * @param digit {number} 精度，保留的小数点数，比如 2, 即保留为两位小数
 *
 */
Vue.prototype.formatNum = function(f, digit) {
	var m = Math.pow(10, digit)
	return parseInt(f * m, 10) / m
}

// 保留两位小数(补0)
Vue.prototype.Fixed = function(count, fl) {
	count += ''
	fl == undefined ? fl = 2 : ''
	let rs = count.indexOf('.')
	if(rs < 0) {
		count += '.'
		for(let i = 0; i < fl; i++) {
			count += '0'
		}
		return count
	}
	while(count.length <= rs + fl) {
		count += '0'
	}
	return count.substr(0, rs + (Number(fl) + 1))
}

// 列表导出
// jsonData：导出列表
// str：导出列表标题(和jsonData对应)
// name：导出列表名称
Vue.prototype.downLoad = function(jsonData, str, name) {
	var str = str
	for(let i = 0; i < jsonData.length; i++) {
		for(let item in jsonData[i]) {
			str += `${jsonData[i][item] + '\t'},`
		}
		str += '\n'
	}
	let uri =
		'data:text/csv;charset=utf-8,\ufeff' +
		encodeURIComponent(str)
	var link = document.createElement('a')
	var blob = new Blob(['\ufeff' + str], {
		type: 'text/csv'
	}) // 解决大文件下载失败
	link.setAttribute('href', URL.createObjectURL(blob))
	link.download = name + '.csv'
	document.body.appendChild(link)
	link.click()
	this.dcShow = false
	document.body.removeChild(link)
	iView.Message.info('导出成功！')
}

// 格式化levelId
Vue.prototype.levelIdFormat = function(id) {
	switch(id) {
		case 0:
			return 'V0'
			break
		case 1:
			return 'V1'
			break
		case 2:
			return 'V2'
			break
		case 3:
			return 'V3'
			break
		default:
			return '#'
			break
	}
}

// 格式化nodeId
Vue.prototype.nodeIdFormat = function(id) {
	switch(id) {
		case 1:
			return '普通节点'
			break
		case 2:
			return '超级节点'
			break
		case 3:
			return '社区节点'
			break
		case 4:
			return '至尊节点'
			break
		default:
			return '#'
			break
	}
}

// 格式化coinId
Vue.prototype.coinIdFormat = function(id) {
	switch(id) {
		case 1:
			return 'USDT'
			break
		case 2:
			return 'Estate'
			break
		default:
			return '#'
			break
	}
}

Vue.prototype.selectList = [{
	id: 0,
	title: 'V0'
}, {
	id: 1,
	title: 'V1'
}, {
	id: 2,
	title: 'V2'
}, {
	id: 3,
	title: 'V3'
}]

/**
 * 左补齐字符串
 *
 * @param nSize
 *            要补齐的长度
 * @param ch
 *            要补齐的字符
 * @return
 */
String.prototype.padLeft = function(nSize, ch) {
	var len = 0
	var s = this ? this : ''
	ch = ch || '0' // 默认补0

	len = s.length
	while(len < nSize) {
		s = ch + s
		len++
	}
	return s
}

/**
 * 右补齐字符串
 *
 * @param nSize
 *            要补齐的长度
 * @param ch
 *            要补齐的字符
 * @return
 */
String.prototype.padRight = function(nSize, ch) {
	var len = 0
	var s = this ? this : ''
	ch = ch || '0' // 默认补0

	len = s.length
	while(len < nSize) {
		s = s + ch
		len++
	}
	return s
}
/**
 * 左移小数点位置（用于数学计算，相当于除以Math.pow(10,scale)）
 *
 * @param scale
 *            要移位的刻度
 * @return
 */
String.prototype.movePointLeft = function(scale) {
	var s, s1, s2, ch, ps, sign
	ch = '.'
	sign = ''
	s = this ? this : ''

	if(scale <= 0) return s
	ps = s.split('.')
	s1 = ps[0] ? ps[0] : ''
	s2 = ps[1] ? ps[1] : ''
	if(s1.slice(0, 1) == '-') {
		s1 = s1.slice(1)
		sign = '-'
	}
	if(s1.length <= scale) {
		ch = '0.'
		s1 = s1.padLeft(scale)
	}
	return sign + s1.slice(0, -scale) + ch + s1.slice(-scale) + s2
}
/**
 * 右移小数点位置（用于数学计算，相当于乘以Math.pow(10,scale)）
 *
 * @param scale
 *            要移位的刻度
 * @return
 */
String.prototype.movePointRight = function(scale) {
	var s, s1, s2, ch, ps
	ch = '.'
	s = this ? this : ''

	if(scale <= 0) return s
	ps = s.split('.')
	s1 = ps[0] ? ps[0] : ''
	s2 = ps[1] ? ps[1] : ''
	if(s2.length <= scale) {
		ch = ''
		s2 = s2.padRight(scale)
	}
	return s1 + s2.slice(0, scale) + ch + s2.slice(scale, s2.length)
}
/**
 * 移动小数点位置（用于数学计算，相当于（乘以/除以）Math.pow(10,scale)）
 *
 * @param scale
 *            要移位的刻度（正数表示向右移；负数表示向左移动；0返回原值）
 * @return
 */
String.prototype.movePoint = function(scale) {
	if(scale >= 0) {
		return this.movePointRight(scale)
	} else {
		return this.movePointLeft(-scale)
	}
}

// 加法
Number.prototype.add = function(arg) {
	var n, n1, n2, s, s1, s2, ps

	s1 = this.toString()
	ps = s1.split('.')
	n1 = ps[1] ? ps[1].length : 0

	s2 = arg.toString()
	ps = s2.split('.')
	n2 = ps[1] ? ps[1].length : 0

	n = n1 > n2 ? n1 : n2
	s = Number(s1.movePoint(n)) + Number(s2.movePoint(n))
	s = s.toString().movePoint(-n)
	return Number(s)
}

// 减法
Number.prototype.sub = function(arg) {
	var n, n1, n2, s, s1, s2, ps

	s1 = this.toString()
	ps = s1.split('.')
	n1 = ps[1] ? ps[1].length : 0

	s2 = arg.toString()
	ps = s2.split('.')
	n2 = ps[1] ? ps[1].length : 0

	n = n1 > n2 ? n1 : n2
	s = Number(s1.movePoint(n)) - Number(s2.movePoint(n))
	s = s.toString().movePoint(-n)
	return Number(s)
}

// 乘法
Number.prototype.mul = function(arg) {
	var n, n1, n2, s, s1, s2, ps

	s1 = this.toString()
	ps = s1.split('.')
	n1 = ps[1] ? ps[1].length : 0

	s2 = arg.toString()
	ps = s2.split('.')
	n2 = ps[1] ? ps[1].length : 0

	n = n1 + n2
	s = Number(s1.replace('.', '')) * Number(s2.replace('.', ''))
	s = s.toString().movePoint(-n)
	return Number(s)
}

// 除法
Number.prototype.div = function(arg) {
	var n, n1, n2, s, s1, s2, ps

	s1 = this.toString()
	ps = s1.split('.')
	n1 = ps[1] ? ps[1].length : 0

	s2 = arg.toString()
	ps = s2.split('.')
	n2 = ps[1] ? ps[1].length : 0

	n = n1 - n2
	s = Number(s1.replace('.', '')) / Number(s2.replace('.', ''))
	s = s.toString().movePoint(-n)
	return Number(s)
}

/**
 * 获取日期（用于获取系统日期）
 *
 * @param day
 *            0是获取今日日期，-7是获取一个星期前的日期，7是获取一个星期后的日期
 * @return
 */
Vue.prototype.getDay = function(day) {
	var today = new Date()

	var targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day

	today.setTime(targetday_milliseconds) // 注意，这行是关键代码

	var tYear = today.getFullYear()
	var tMonth = today.getMonth()
	var tDate = today.getDate()
	tMonth = this.doHandleMonth(tMonth + 1)
	tDate = this.doHandleMonth(tDate)
	return tYear + '-' + tMonth + '-' + tDate
}
Vue.prototype.doHandleMonth = function(month) {
	var m = month
	if(month.toString().length == 1) {
		m = '0' + month
	}
	return m
}

// 全局时间处理过滤器
Vue.filter('dateformat', (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') => {
	return moment(dataStr).format(pattern)
})

router.beforeEach((to, from, next) => {
	iView.LoadingBar.start()
	let token = localStorage.getItem('mytoken')
	// next()
	
	//	如果已经登录， 不干涉访问
	if(localStorage.mytoken) {
		axios.defaults.headers['Authorization'] = 'bearer ' + localStorage.mytoken
		next()
	} else {
		axios.defaults.headers['Authorization'] = ''
		localStorage.clear()
		if(to.path !== '/login') {
			// 如果没有登录，但访问其他需要登录的页面，就让你跳到登录页面去
			next({
				path: '/login'
			})
		} else {
			// 如果没有登录，但你访问的login，那就不干涉访问
			next()
		}
	}
})

// 响应拦截（配置请求回来的信息）
axios.interceptors.response.use(response => {
	// 处理响应数据
	// 判断如果请求返回401状态码，即登录超时，清除mytoken并跳回登录页
	// alert(response.data.code)
	if(response.data.code === 401) {
		router.push('/login')
		localStorage.clear()
		iView.Message.info(response.data.msg)
	} else if(response.data.code === 500) {
		iView.Message.info(response.data.msg)
	}
	return response
}, error => {
	// 处理响应失败
	if(error.response) {
		iView.Message.info(error.response.data.msg)
	}
	return Promise.reject(error)
})

axios.interceptors.request.use(
	config => {
		config.withCredentials = true // 允许携带token ,这个是解决跨域产生的相关问题

		if(localStorage.mytoken) {
			config.headers.Authorization = 'bearer ' + localStorage.mytoken
		}
		return config
	},
	error => {
		return Promise.reject(error)
	}
)

router.afterEach((transition) => {
	iView.LoadingBar.finish()
})

// import '@/mock'
// 实际打包时应该不引入mock
/* eslint-disable */
if(process.env.NODE_ENV !== 'production') require('@/mock')

Vue.use(iView, {
	i18n: (key, value) => i18n.t(key, value)
})
Vue.config.productionTip = false
/**
 * @description 全局注册应用配置
 */
Vue.prototype.$config = config
/**
 * 注册指令
 */
importDirective(Vue)

/* eslint-disable no-new */
new Vue({
	el: '#app',
	router,
	i18n,
	store,
	render: h => h(App)
})